#ifndef FTP_DOWNLOADER_H
#define FTP_DOWNLOADER_H

#include <memory>
#include <functional>
#include <string>
#include <thread>
#include <curl/curl.h>
#include "FtpDelegate.h"

//连接握手超时时间20秒，完成超时时间不限制
#define CONNECT_SECOND 20
#define COMPLETE_SECOND 0

/* abort if slower than 256B/s during 10 seconds */
#define MIN_SPEED 256
#define MIN_SPEED_SECOND 10

using namespace std;

class FtpDownloader : public  FtpDelegate
{
public:
    typedef std::shared_ptr<FtpDownloader> Ptr;
    friend size_t curl_onDownload(void *buffer, size_t size, size_t nmemb, void *stream);
    friend size_t curl_onHeader(void *buffer, size_t size, size_t nmemb, void *stream);
    friend int curl_onProgress(void *clientp,   curl_off_t dltotal,   curl_off_t dlnow,   curl_off_t ultotal,   curl_off_t ulnow);

    typedef function<void()> onDownloadResult;
    FtpDownloader(const string &user_name,const string &passwd);
    virtual ~FtpDownloader();
public:
    //异步开始下载，如果已经在下载返回false;默认15秒内完成握手,不限制下载成功时间
    bool start(const string &url,int offset = 0,int connectTimeoutSec = CONNECT_SECOND,int completeTimeoutSec = COMPLETE_SECOND);
    //暂停下载，此时socket并未close掉，后台线程也未退出
    bool pause(bool flag = true);
    //中途取消下载
    bool cancel();
    //等待操作完成
    void wait();
    //下载速度
    int downloadSpeed();
    //设置下载低速自动断开限制,在开始下载前设置有效
    void setLowSpeedLimit(int minSpeed,int minSpeedSec);
private:
    bool canceled() const ;
    int onProgressInner(char *data,int size);
    void startDownload(const string &url,int offset,int connectTimeoutSec,int completeTimeoutSec);
private:
    string _user_name;
    string _passwd;
    double _total = 0;
    long _fileTime = 0;
    int _offset = 0;
    CURL *_curl = nullptr;
    bool _cancel = false;
    int _minSpeed = MIN_SPEED;
    int _minSpeedSec = MIN_SPEED_SECOND;
    std::shared_ptr<thread> _thread;
    std::recursive_mutex _mtx;
};




#endif //FTP_DOWNLOADER_H